
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BButtonGroup>
#include <BReadWrite>
#include <BScene>
#include <BFile>
#include <BEntry>
#include <BFolder>
#include <BStyle>
#include <BSystem>

#include "Target.h"
#include "ImportDialog.h"

ImportDialog::ImportDialog(BWidget* parent) : BDialog(parent)
{
	this->setTitle("Import Objects");
	this->setSize(600, 400);

	_treeWidget = new BTreeWidget();
	_folderGroupBox = new BGroupBox("Folder As Group");
	_folderGroupBox->setAlign(Align_LeftCenter);
	_folderGroupBox->setCheckable(true);
	_folderGroupBox->setChecked(true);
	{
		_childFolderCheckBox = new BCheckBox("Read child folders");

		BVBoxLayout* vlayout = new BVBoxLayout(_folderGroupBox);
		vlayout->addWidget(_childFolderCheckBox);
		vlayout->addSpring();
	}
	BHBoxLayout* hlayout = new BHBoxLayout(this);
	hlayout->addWidget(_treeWidget);
	hlayout->addWidget(_folderGroupBox, 0);

	BHBoxLayout* bottomLayout = new BHBoxLayout(this, Part_Bottom);
	{
		_importButton = new BButton("Import");
		_cancelButton = new BButton("Cancel");
		bottomLayout->addSpring();
		bottomLayout->addWidget(_importButton);
		bottomLayout->addWidget(_cancelButton);
	}

	connect(_folderGroupBox, Signal_Checked, &ImportDialog::slotFolderGroupBoxToggled);
	connect(_importButton, Signal_Clicked, &ImportDialog::slotImportButtonClicked);
	connect(_cancelButton, Signal_Clicked, &ImportDialog::slotCancelButtonClicked);
}
ImportDialog::~ImportDialog()
{

}

void ImportDialog::setFileNames(const BStringList& fileNames)
{
	_treeWidget->clearItems();
	bool hasFolder = false;
	for (auto fileName : fileNames)
	{
		BTreeItem* item = _treeWidget->addTopItem(fileName);
		if (BFile::Exist(fileName))
			item->setAsset(ReadFile(fileName));
		if (BFolder::Exist(fileName))
		{
			item->setProperty("folder", new BFolder(fileName));
			hasFolder = true;
		}
	}
	_folderGroupBox->setEnabled(hasFolder);
	if (hasFolder && _folderGroupBox->checked())
	{
		for (int i = 0; i < _treeWidget->topItemCount(); i++)
		{
			BTreeItem* item = _treeWidget->topItem(i);
			openFolderItem(item);
		}
	}
	for (int i = 0; i < _treeWidget->topItemCount(); i++)
	{
		BTreeItem* item = _treeWidget->topItem(i);
		freshItemIcon(item);
	}
}

void ImportDialog::freshItemIcon(BTreeItem* item)
{
	item->setIcon(0);
	item->setImage(0);
	if (BObject* object = item->asset())
	{
		const BStyle* style = this->realStyle();
		for (int i = object->typeCount() - 1; i >= 0; i--)
		{
			const char* type = object->typeName(i);
			if (BIcon* icon = style->icon(type))
			{
				item->setIcon(icon);
				continue;
			}
			if (BImage* image = style->image(type))
			{
				item->setImage(image);
				continue;
			}
		}
	}
	else
	{
		if (BFolder* folder = item->property("folder"))
		{
			BIcon* icon = BSystem::EntryIcon(folder->path());
			item->setIcon(icon);
		}
	}
}
void ImportDialog::openFolderItem(BTreeItem* item)
{
	BFolder* folder = item->property("folder");
	if (folder == 0)
		return;
	if (folder->open())
	{
		BGroup* folderGroup = new BGroup(folder->path().name());
		for (int i = 0; i < folder->entryCount(); i++)
		{
			const BString& filePath = folder->entry(i)->path();
			if (BFolder::Exist(filePath))
			{
				BTreeItem* child = item->addChild(filePath);
				child->setProperty("folder", new BFolder(filePath));
				continue;
			}
			if (BObject* object = ReadFile(filePath))
			{
				BTreeItem* child = item->addChild(filePath);
				child->setAsset(object);
				if (BShape* shape = dynamic_cast<BShape*>(object))
				{
					folderGroup->insert(shape);
				}
				else if (BNode* node = dynamic_cast<BNode*>(object))
				{
					folderGroup->insert(node);
				}
				else if (BGroup* group = dynamic_cast<BGroup*>(object))
				{
					folderGroup->addChild(group);
				}
				else if (BScene* scene = dynamic_cast<BScene*>(object))
				{
					for (int i = 0; i < scene->shapeCount(); i++)
					{
						BShape* shape = scene->shape(i);
						folderGroup->insert(shape);
					}
				}
			}
			else
			{
				_message << "Read file failed :" << filePath << '\n';
			}
		}
		item->setAsset(folderGroup);
		folder->close();
	}
	else
	{
		_message << "Open folder failed :" << folder->path() << '\n';
	}
	if (_childFolderCheckBox->checked())
	{
		for (int i = 0; i < item->childCount(); i++)
		{
			BTreeItem* child = item->child(i);
			openFolderItem(child);
		}
	}
	for (int i = 0; i < item->childCount(); i++)
	{
		BTreeItem* child = item->child(i);
		freshItemIcon(child);
	}
}
void ImportDialog::closeFolderItem(BTreeItem* item)
{

}

void ImportDialog::slotFolderGroupBoxToggled(BObject* object, const BValue& value)
{
	for (int i = 0; i < _treeWidget->topItemCount(); i++)
	{
		BTreeItem* item = _treeWidget->topItem(i);
		if (_folderGroupBox->checked())
		{
			openFolderItem(item);
		}
		else
		{
			closeFolderItem(item);
		}
	}
}
void ImportDialog::slotImportButtonClicked(BObject* object, const BValue& value)
{
	if (Target* target = this->asset())
	{
		BScene* scene = target->scene();
		for (int i = 0; i < _treeWidget->topItemCount(); i++)
		{
			BTreeItem* item = _treeWidget->topItem(i);
			if (BShape* shape = item->asset())
				scene->insert(shape);
			else if (BNode* node = item->asset())
				scene->insert(node);
			else if (BGroup* group = item->asset())
				scene->insert(group);
			else if (BConstraint* constraint = item->asset())
				scene->insert(constraint);
		}
	}
	this->close(1);
}
void ImportDialog::slotCancelButtonClicked(BObject* object, const BValue& value)
{
	this->close(0);
}

void ImportDialog::styleEvent(const BEvent& event)
{

}
